const vscode = require('vscode');
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const postcss = require("postcss");
const postcssScss = require("postcss-scss");
const recast = require("recast");
const types = recast.types;
const b = types.builders;

function activate(context) {

	// 存储选中的文件
	let selectedFiles = {};
	// 注册"选择第一个文件"命令
	const selectScssFile = vscode.commands.registerCommand('extension.selectScss', (uri) => {
		selectedFiles.first = uri.fsPath;
		// 更新上下文，控制菜单显示
		vscode.commands.executeCommand('setContext', 'fileComparatorScssFileSelected', true);
	});

	// 注册"选择第二个文件"命令
	const selectJSFile = vscode.commands.registerCommand('extension.selectJs', (uri) => {
		selectedFiles.second = uri.fsPath;

		// 重置上下文状态
		vscode.commands.executeCommand('setContext', 'fileComparatorScssFileSelected', false);

		// 自动执行比较
		if (selectedFiles.first && selectedFiles.second) {
			try {
				function handleScss() {
					const targetProps = [
						"display:flex",
						"align-items:center",
						"flex-direction:column",
						"justify-content:center",
						"justify-content:space-between",
						"justify-content:space-around",
						"justify-content:flex-end",
						"align-items:flex-end",
						"align-items:flex-start",
						"align-items:center",
						// 可以继续添加其他属性
					].map(prop => prop.replace(/\s+/g, "")); // 移除所有空格，确保匹配

					function areArraysEqual(arr1, arr2) {
						// 如果两个数组长度不同，直接返回false
						if (arr1.length !== arr2.length) {
							return false;
						}

						// 创建一个对象来记录第一个数组中每个元素的出现次数
						const elementCounts = {};

						// 统计第一个数组的元素
						for (const element of arr1) {
							elementCounts[element] = (elementCounts[element] || 0) + 1;
						}

						// 检查第二个数组的元素
						for (const element of arr2) {
							// 如果元素不存在或计数为0，返回false
							if (!elementCounts[element]) {
								return false;
							}
							elementCounts[element]--;
						}

						return true;
					}

					const clssNameNum = {
						// "display:flex": "flex_row",
						"display:flex,flex-direction:column": "flex_col",

						"display:flex,justify-content:center": "row_start_center",
						"display:flex,justify-content:space-between": "row_start_between",
						"display:flex,justify-content:space-around": "row_start_around",
						"display:flex,justify-content:flex-end": "row_start_end",

						"display:flex,align-items:center": "row_center_start",
						"display:flex,align-items:center,justify-content:space-between": "row_center_between",
						"display:flex,align-items:center,justify-content:space-around": "row_center_around",
						"display:flex,align-items:center,justify-content:flex-end": "row_center_end",

						"display:flex,align-items:flex-end": "row_end_start",
						"display:flex,align-items:flex-end,justify-content:space-between": "row_end_between",
						"display:flex,align-items:flex-end,justify-content:space-around": "row_end_around",
						"display:flex,align-items:flex-end,justify-content:center": "row_end_center",

						"display:flex,justify-content:center,align-items:center": "row_cc",

						"display:flex,flex-direction:column,justify-content:center": "col_start_center",
						"display:flex,flex-direction:column,justify-content:space-between": "col_start_between",
						"display:flex,flex-direction:column,justify-content:space-around": "col_start_around",
						"display:flex,flex-direction:column,justify-content:flex-end": "col_start_end",

						"display:flex,flex-direction:column,align-items:center": "col_center_start",
						"display:flex,flex-direction:column,align-items:center,justify-content:space-between": "col_center_between",
						"display:flex,flex-direction:column,align-items:center,justify-content:space-around": "col_center_around",
						"display:flex,flex-direction:column,align-items:center,justify-content:flex-end": "col_center_end",

						"display:flex,flex-direction:column,align-items:flex-end": "col_end_start",
						"display:flex,flex-direction:column,align-items:flex-end,justify-content:space-between": "col_end_between",
						"display:flex,flex-direction:column,align-items:flex-end,justify-content:space-around": "col_end_around",
						"display:flex,flex-direction:column,align-items:flex-end,justify-content:center": "col_end_center",

						"display:flex,flex-direction:column,justify-content:center,align-items:center": "col_cc",
					}

					function main() {
						const scssFile = path.resolve(selectedFiles.first);
						const scssContent = fs.readFileSync(scssFile, "utf8");
						const result = postcss().process(scssContent, { syntax: postcssScss, from: undefined });
						const removedLog = {};

						result.root.walkRules(rule => {
							function getFullSelector(rule_) {
								let selector = rule_.selector;
								let parent = rule_.parent;
								while (parent && parent.type === 'rule') {
									// 替换&为父选择器
									selector = selector.replace(/&/g, parent.selector);
									parent = parent.parent;
								}

								if (!selector.includes('.') || selector.includes(':') || selector.includes('>') || selector.includes('~') || selector.includes('+')) {
									return
								}

								if (selector.includes(',')) {
									selector = selector.split(',');
									return selector.filter(item => item.includes('.')).map(item => item.split('.')[1])
								}

								return [selector.split('.')[1]];
							};

							const selector = getFullSelector(rule);
							const newProps = [];
							const removeList = [];

							if (!selector) {
								return
							}

							rule.walkDecls(decl => {
								const normalizedDecl = `${decl.prop}:${decl.value}`.replace(/\s+/g, '');
								// 精确匹配（属性名+值完全一致）
								if (targetProps.includes(normalizedDecl) && decl.parent === rule) {
									removeList.push(decl.remove.bind(decl));
									newProps.push(normalizedDecl);
									// 记录被删除的属性
									// if (!removedLog[selector]) {
									//   removedLog[selector] = [];
									// }
									// removedLog[selector].push({
									//   property: decl.prop,
									//   value: decl.value,
									//   line: decl.source?.start?.line, // 源代码行号
									// });
								};
							});

							const isMatch = Object.keys(clssNameNum).some((v) => {
								const k = areArraysEqual(newProps, v.split(','));
								if (k) {
									selector.forEach(s => removedLog[s] = clssNameNum[v])
									removeList.forEach(fn => fn());
									return true;
								};
							});

							if (!isMatch) {
								delete removedLog[selector];
							};
						});

						console.log('结果：', removedLog);
						fs.writeFileSync(scssFile, result.css, "utf8");
						return removedLog
					};
					return main();
				};
				function handleJs(removedScssObject) {
					const jsFile = path.resolve(selectedFiles.second);
					const code = fs.readFileSync(jsFile, "utf-8");
					const ast = recast.parse(code, {
						parser: require("recast/parsers/babel"), // 使用 Babel 解析器解析 JSX
						tabWidth: 2, // 保持缩进
						quote: "auto", // 保留原始引号风格
						trailingComma: true, // 保留末尾逗号
						lineTerminator: "\n", // 保留换行符
						jsx: true, // 确保正确解析 JSX
					});

					const handledClassNames = []

					// 遍历 AST，修改所有 JSX 的 className 属性
					recast.visit(ast, {
						visitJSXAttribute(path) {
							const { node } = path;

							if (node.name.name === "className") {
								// console.log('className', node.value.type);

								if (node.value.type === 'JSXExpressionContainer') {
									const expression = node.value.expression;

									if (expression.type === 'MemberExpression') {
										// className={styles.recommend} --> className={classnames(styles.recommend, "row_cc")}
										if (expression.object.name === 'styles') {
											const newClassName = removedScssObject[expression.property.name]
											if (newClassName) {
												const classnamesCall = b.callExpression(
													b.identifier("classnames"),
													[
														expression,
														b.literal(newClassName)
													]
												);
												handledClassNames.push(expression.property.name)
												node.value.expression = classnamesCall;
											}
										}
									} else if (expression.type === 'ConditionalExpression') {
										// className={true ? 'recommend-title uu' : 'fullReturn-loading'} --> className={true ? "recommend-title uu row_cc" : "fullReturn-loading row_center_start"}
										const consequent = expression.consequent.value.split(' ');
										const newconsequent = [...consequent]
										consequent.forEach(item => {
											if (removedScssObject[item]) {
												handledClassNames.push(item)
												newconsequent.push(removedScssObject[item]);
											}
										});
										node.value.expression.consequent.value = newconsequent.join(' ');

										const alternate = expression.alternate.value.split(' ');
										const newalternate = [...alternate]
										alternate.forEach(item => {
											if (removedScssObject[item]) {
												handledClassNames.push(item)
												newalternate.push(removedScssObject[item]);
											}
										});
										node.value.expression.alternate.value = newalternate.join(' ');
									} else if (expression.type === 'CallExpression') {
										let newArguments = '';
										// TODO 转成小写
										if (expression.callee.name.toLowerCase() === 'classnames') {
											expression.arguments.forEach(item => {
												// className={classnames('recommend', 'recommend uu')} --> className={classnames('recommend row_cc', 'recommend uu row_cc')}
												if (item.type === 'StringLiteral') {
													const oldClassName = item.value.split(' ');
													const newClassName = [...oldClassName]
													oldClassName.forEach(k => {
														if (removedScssObject[k]) {
															handledClassNames.push(k)
															newClassName.push(removedScssObject[k]);
														}
													});
													if (newClassName.length > oldClassName.length) {
														item.value = newClassName.join(' ')
													}
												} else if (item.type === 'ObjectExpression') {
													// className={classnames({ recommend: true })} --> className={classnames({ "recommend row_cc": true })}
													if (item.properties[0].key.type === "Identifier") {
														const oldClassName = item.properties[0].key.name.split(' ');
														const newClassName = [...oldClassName]
														oldClassName.forEach(k => {
															if (removedScssObject[k]) {
																handledClassNames.push(k)
																newClassName.push(removedScssObject[k]);
															}
														});
														if (newClassName.length !== oldClassName.length) {
															item.properties[0].key.name = `"${newClassName.join(' ')}"`
														}
													} else if (item.properties[0].key.type === "StringLiteral") {
														// className={classnames({ "recommend": true })} --> className={classnames({ "recommend row_cc": true })}
														const oldClassName = item.properties[0].key.value.split(' ');
														const newClassName = [...oldClassName]
														oldClassName.forEach(k => {
															if (removedScssObject[k]) {
																handledClassNames.push(k)
																newClassName.push(removedScssObject[k]);
															}
														});
														if (newClassName.length !== oldClassName.length) {
															item.properties[0].key.value = newClassName.join(' ');
														}
													}
												} else if (item.type === 'MemberExpression') {
													// className={classnames(styles.recommend)} --> className={classnames(styles.recommend, "row_cc")}
													if (item.object.name === 'styles') {
														if (item.property.type === 'Identifier') {
															const oldClassName = item.property.name
															const newClassName = removedScssObject[oldClassName];
															if (newClassName) {
																handledClassNames.push(oldClassName)
																newArguments += ` "${newClassName}"`
															}
														}
													}
												}
											});
											if (newArguments.length > 0) {
												expression.arguments.push(newArguments);
											}
										}
									}
								} else if (node.value.type === 'StringLiteral') {
									//  className="recommend-title row_cc" --> className="recommend-title"
									const oldClassList = node.value.value.split(' ')
									const newClassList = [...oldClassList]
									oldClassList.forEach(item => {
										if (removedScssObject[item]) {
											handledClassNames.push(item)
											newClassList.push(removedScssObject[item])
										}
									})
									node.value.value = newClassList.join(' ')
								}
							}

							// 继续遍历
							return this.traverse(path);
						}
					});

					console.log('已处理的类名：', [...new Set(handledClassNames)])
					// console.log('scss已删除但对应元素未处理的类名', Object.keys(removedScssObject).filter(v => !handledClassNames.includes(v)).map(v => ({ [v]: removedScssObject[v] })));

					const noHandledClassNames = {}
					Object.keys(removedScssObject).filter(v => !handledClassNames.includes(v)).forEach((v) => {
						noHandledClassNames[v] = removedScssObject[v]
					})
					const outputChannel = vscode.window.createOutputChannel('extension.delflex');

					// 显示长消息时
					outputChannel.clear();
					outputChannel.appendLine("scss已删除但对应元素未处理的类名: " + JSON.stringify(noHandledClassNames, null, 2));
					outputChannel.show();

					const output = recast.print(ast, {
						reuseWhitespace: true, // 强制复用原始空白符
						lineTerminator: "\n",
					}).code;
					fs.writeFileSync(jsFile, output);
				};

				const removedScssObject = handleScss()
				handleJs(removedScssObject)
			} catch (error) {
				selectedFiles = {}
			}
			selectedFiles = {}
		}
	});

	context.subscriptions.push(selectScssFile, selectJSFile);
}

function deactivate() { }

module.exports = {
	activate,
	deactivate
}